package com.excilys.controller;

import java.util.List;

import javax.persistence.NoResultException;
import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.excilys.model.Logbar;
import com.excilys.model.TransferErrorType;
import com.excilys.model.TransferForm;
import com.excilys.model.User;
import com.excilys.service.AccountService;
import com.excilys.service.TransferFormService;
import com.excilys.service.UserService;
import com.excilys.utils.UserUtils;

/**
 * Class that takes care of the user's transfers page
 * 
 * @author excilys dev : NT, GF
 * 
 */
@Controller
@RequestMapping(value = "/transfers")
public class TransfersController {

	@Autowired
	private AccountService myAccountService;
	@Autowired
	private UserService myUserService;
	@Autowired
	private TransferFormService transferService;

	@RequestMapping(value = "/management", method = RequestMethod.GET)
	public String transfersAccountsManagement(Model model) {
		(new Logbar()).setContent(model);
		return "transfers-accounts-management";
	}

	/**
	 * Displays the transfer form
	 * 
	 * @param model
	 * @param principal
	 * @return
	 */
	@RequestMapping(value = "/management/account-adding", method = RequestMethod.POST)
	public String transfersAccountsAdding(@ModelAttribute("accountToAdd") String accountToAdd, Model model, RedirectAttributes redirectAttrs) {
		(new Logbar()).setContent(model);
		boolean error = false;
		try {
			myUserService.addTargetAccountToUser(UserUtils.getConnectedUser(), myAccountService.getAccountByNameNotSecured(accountToAdd));
		} catch (NoResultException noResult) {
			error = true;
			redirectAttrs.addFlashAttribute("error", error);
			return "redirect:/transfers/management";
		}
		redirectAttrs.addFlashAttribute("accountToAdd", accountToAdd);
		return "redirect:/transfers/management/account-added";
	}

	@RequestMapping(value = "/management/account-added", method = RequestMethod.GET)
	public String transfersAccountsAdded(Model model) {
		(new Logbar()).setContent(model);
		return "transfers-account-added";
	}

	@RequestMapping(value = "/generate", method = RequestMethod.GET)
	public String transferGenerate(Model model) {
		(new Logbar()).setContent(model);

		User currentUser = UserUtils.getConnectedUser();
		model.addAttribute("accountList", currentUser.getUserListAccounts());
		model.addAttribute("targetList", currentUser.getUserTargetAccounts());
		model.addAttribute("transferForm", new TransferForm());
		return "transfer-generate";
	}

	/**
	 * Handles the posting of the transfer form. Uses Services that use
	 * validation processes
	 * 
	 * @param transferForm
	 * @param result
	 * @param model
	 * @param principal
	 * @return
	 */
	@RequestMapping(value = "/generate", method = RequestMethod.POST)
	public String generateTransfer(@Valid TransferForm transferForm, BindingResult result, Model model) {
		List<TransferErrorType> transferErrorType = transferService.checkTransfer(transferForm);
		if (transferErrorType.contains(TransferErrorType.UNAVAILABLE_AMOUNT)) {
			model.addAttribute("amountError", "The selected account does not have such an amount.");
		} else if (transferErrorType.contains(TransferErrorType.SAME_ACCOUNTS)) {
			model.addAttribute("accountError", "The selected accounts are the same.");
		} else if (!result.hasErrors()) {
			transferService.persistTransfer(transferForm);
			return "redirect:/transfers/transfer-success";
		}

		(new Logbar()).setContent(model);
		User currentUser = UserUtils.getConnectedUser();
		model.addAttribute("accountList", currentUser.getUserListAccounts());
		model.addAttribute("targetList", currentUser.getUserTargetAccounts());
		model.addAttribute("transferForm", transferForm);
		return "transfer-generate";

	}

	/**
	 * Displays the transfer-success jsp when the transfer is successful
	 * 
	 * @param model
	 * @param principal
	 * @return
	 */
	@RequestMapping(value = "/transfer-success", method = RequestMethod.GET)
	public String generateTransfer(Model model) {
		(new Logbar()).setContent(model);
		return "transfer-success";
	}
}
